---
title: 经典列表
docs:
  - route: /docs/components/list-classic-node
    title: 列表节点
  - route: /docs/components/list-classic-toolbar-button
    title: 列表工具栏按钮
---

<ComponentPreview name="list-classic-demo" />

<Callout type="info" title="选择您的列表插件">
  Plate 提供两种实现列表的方法：

  1. **此经典列表插件** - 具有严格嵌套规则的传统 HTML 规范列表：
     - 遵循标准 HTML 列表结构（`ul`/`ol` > `li`）
     - 保持一致的列表层次结构
     - 最适合可能导出为 HTML/markdown 的内容
     - 复杂度最高

  2. [**列表插件**](/docs/list) - 灵活的基于缩进的列表：
     - 更像 Word/Google Docs 的行为
     - 任何块都可以缩进以创建类似列表的结构
     - 在 [AI 编辑器](/editors#editor-ai) 中使用
     - 支持嵌套待办事项列表
     - 更适合自由形式的内容组织

  根据您的需求选择：
  - 当您需要标准 HTML 列表兼容性时，使用**经典列表插件**
  - 当您想要更灵活的缩进行为时，使用**列表插件**

</Callout>

<PackageInfo>

## 功能

- **符合 HTML 的列表**：
  - 标准 `ul`/`ol` > `li` 结构
  - 正确的嵌套和层次结构
  - SEO 友好的标记
  - 干净的 HTML/markdown 导出

- **列表类型**：
  - 无序（项目符号）列表
  - 有序（编号）列表
  - 带复选框的任务列表
  - 嵌套子列表

- **拖放**：
  - 目前仅支持根级列表项
  - 同级和嵌套项拖放尚未支持

- **快捷键**：
  - 结合自动格式化插件，使用 markdown 快捷键（**`-`**、**`*`**、**`1.`**、**`[ ]`**）创建列表
  - Tab/Shift+Tab 用于缩进控制

- **限制（使用 [列表插件](/docs/list) 获取这些功能）**：
  - 拖放仅支持根级列表
  - 列表项无法对齐

对于更灵活的、类似 Word 的方法，请参阅[列表插件](/docs/list)。

</PackageInfo>

## 套件使用

<Steps>

### 安装

添加列表功能的最快方法是使用 `ListKit`，它包含预配置的列表插件，带有 [Plate UI](/docs/installation/plate-ui) 组件和键盘快捷键。

<ComponentSource name="list-classic-kit" />

- [`BulletedListElement`](/docs/components/list-classic-node)：渲染无序列表元素。
- [`NumberedListElement`](/docs/components/list-classic-node)：渲染有序列表元素。
- [`TaskListElement`](/docs/components/list-classic-node)：渲染带复选框的任务列表元素。

### 添加套件

将套件添加到您的插件中：

```tsx
import { createPlateEditor } from 'platejs/react';
import { ListKit } from '@/components/editor/plugins/list-classic-kit';

const editor = createPlateEditor({
  plugins: [
    // ...其他插件,
    ...ListKit,
  ],
});
```

</Steps>

## 手动使用

<Steps>

### 安装

```bash
npm install @platejs/list-classic
```

### 添加插件

在创建编辑器时，将列表插件包含在您的 Plate 插件数组中。

```tsx
import { ListPlugin, BulletedListPlugin, NumberedListPlugin, TaskListPlugin, ListItemPlugin } from '@platejs/list-classic/react';
import { createPlateEditor } from 'platejs/react';

const editor = createPlateEditor({
  plugins: [
    // ...其他插件,
    ListPlugin,
    BulletedListPlugin,
    NumberedListPlugin,
    TaskListPlugin,
    ListItemPlugin,
  ],
});
```

### 配置插件

使用自定义组件和键盘快捷键配置插件。

```tsx
import { ListPlugin, BulletedListPlugin, NumberedListPlugin, TaskListPlugin, ListItemPlugin } from '@platejs/list-classic/react';
import { createPlateEditor } from 'platejs/react';
import { BulletedListElement, NumberedListElement, TaskListElement } from '@/components/ui/list-classic-node';

const editor = createPlateEditor({
  plugins: [
    // ...其他插件,
    ListPlugin,
    BulletedListPlugin.configure({
      node: { component: BulletedListElement },
      shortcuts: { toggle: { keys: 'mod+alt+5' } },
    }),
    NumberedListPlugin.configure({
      node: { component: NumberedListElement },
      shortcuts: { toggle: { keys: 'mod+alt+6' } },
    }),
    TaskListPlugin.configure({
      node: { component: TaskListElement },
      shortcuts: { toggle: { keys: 'mod+alt+7' } },
    }),
    ListItemPlugin,
  ],
});
```

- `node.component`：分配 [`BulletedListElement`](/docs/components/list-classic-node)、[`NumberedListElement`](/docs/components/list-classic-node) 和 [`TaskListElement`](/docs/components/list-classic-node) 来渲染列表元素。
- `shortcuts.toggle`：定义键盘[快捷键](/docs/plugin-shortcuts)来切换列表类型（`mod+alt+5` 用于项目符号，`mod+alt+6` 用于编号，`mod+alt+7` 用于任务列表）。

### 添加工具栏按钮

您可以将 [`ListToolbarButton`](/docs/components/list-classic-toolbar-button) 添加到您的[工具栏](/docs/toolbar)中以创建和管理列表。

### 转换为工具栏按钮

使用 `ListPlugin` 时，请使用 [`turn-into-toolbar-classic-button`](/docs/components/turn-into-toolbar-classic-button)，它包含所有列表类型（项目符号、编号和任务列表）。

### 插入工具栏按钮

使用 `ListPlugin` 时，请使用 [`insert-toolbar-classic-button`](/docs/components/insert-toolbar-classic-button)，它包含所有列表类型（项目符号、编号和任务列表）。

</Steps>

## 插件

### `ListPlugin`

<API name="ListPlugin">
包含以下元素插件：
- `BulletedListPlugin`
- `NumberedListPlugin`
- `TaskListPlugin`
- `ListItemPlugin`
- `ListItemContentPlugin`

<APIOptions type="object">
  <APIItem name="validLiChildrenTypes" type="string[]" optional>
    列表项的有效子节点类型（除了 `p` 和 `ul`）。
  </APIItem>
  <APIItem name="enableResetOnShiftTab" type="boolean" optional>
    是否应该用 Shift+Tab 重置列表缩进级别。
  </APIItem>
  <APIItem name="inheritCheckStateOnLineEndBreak" type="boolean" optional>
    是否在行尾插入换行符后继承上方节点的选中状态。仅适用于任务列表。
    - **默认：** `false`
  </APIItem>
  <APIItem name="inheritCheckStateOnLineStartBreak" type="boolean" optional>
    是否在行首插入换行符后继承下方节点的选中状态。仅适用于任务列表。
    - **默认：** `false`
  </APIItem>
</APIOptions>
</API>

### `BulletedListPlugin`

用于无序（项目符号）列表的插件。

### `NumberedListPlugin`

用于有序（编号）列表的插件。

### `TaskListPlugin`

用于带复选框的任务列表的插件。

### `ListItemPlugin`

用于列表项的插件。

### `ListItemContentPlugin`

用于列表项内容的插件。

## 转换

### `tf.ul.toggle()`

切换项目符号列表（ul）。

示例快捷键：`Mod+Alt+5`

### `tf.ol.toggle()`

切换编号列表（ol）。

示例快捷键：`Mod+Alt+6`

### `tf.taskList.toggle()`

切换带复选框的任务列表。

示例快捷键：`Mod+Alt+7`

## API

### `getHighestEmptyList`

查找可以删除的最高端列表。列表的路径应该与 `diffListPath` 不同。如果最高端列表有 2 个或更多项目，则返回 `liPath`。它会向上遍历父列表，直到：
- 列表的项目少于 2 个
- 其路径不等于 `diffListPath`

<API name="getHighestEmptyList">
<APIOptions type="object">
  <APIItem name="liPath" type="Path">
    列表项的路径。
  </APIItem>
  <APIItem name="diffListPath" type="Path" optional>
    不同列表的路径。
  </APIItem>
</APIOptions>

<APIReturns type="Path | undefined">
  最高可删除端列表的路径。
</APIReturns>
</API>

### `getListItemEntry`

返回给定路径的最近 `li` 和 `ul`/`ol` 包装节点条目（`默认 = 选择`）。

<API name="getListItemEntry">
<APIOptions type="object">
  <APIItem name="at" type="Location | null" optional>
    获取条目的位置。
    - **默认：** `editor.selection`
  </APIItem>
</APIOptions>

<APIReturns type="ElementEntry | undefined">
  最近的 `li` 和 `ul`/`ol` 包装节点条目。
</APIReturns>
</API>

### `getListRoot`

向上搜索根列表元素。

<API name="getListRoot">
<APIParameters>
  <APIItem name="at" type="Path | TRange | Point | null" optional>
    开始搜索的位置。
    - **默认：** `editor.selection`
  </APIItem>
</APIParameters>

<APIReturns type="ElementEntry | undefined">
  根列表元素条目。
</APIReturns>
</API>

### `getListTypes`

获取支持的列表类型数组。

<API name="getListTypes">
<APIReturns type="string[]">
  支持的列表类型数组。
</APIReturns>
</API>

### `getTaskListProps`

根据提供的类型返回任务列表项的属性。

<API name="getTaskListProps">
<APIParameters>
  <APIItem name="type" type="string">
    要检查的列表类型。
  </APIItem>
  <APIItem name="options" type="object" optional>
    任务列表选项。
  </APIItem>
  <APISubList>
    <APISubListItem parent="options" name="checked" type="boolean">
      任务项是否应被选中。
      - **默认：** `false`
    </APISubListItem>
  </APISubList>
</APIParameters>

<APIReturns type="object | undefined">
  如果类型是任务列表，则返回带有 `checked` 属性的对象，否则返回 `undefined`。
</APIReturns>
</API>

### `moveListSiblingsAfterCursor`

将光标后的列表兄弟项移动到指定路径。

<API name="moveListSiblingsAfterCursor">
<APIOptions type="options">
  <APIItem name="at" type="Path">
    光标位置路径。
  </APIItem>
  <APIItem name="to" type="Path">
    目标路径。
  </APIItem>
</APIOptions>

<APIReturns type="number">
  移动的兄弟项数量。
</APIReturns>
</API>

### `removeFirstListItem`

如果未嵌套且不是第一个子项，则删除第一个列表项。

<API name="removeFirstListItem">
<APIOptions type="options">
  <APIItem name="list" type="ElementEntry">
    包含项的列表条目。
  </APIItem>
  <APIItem name="listItem" type="ElementEntry">
    要删除的列表项。
  </APIItem>
</APIOptions>

<APIReturns type="boolean">
  项是否被删除。
</APIReturns>
</API>

### `removeListItem`

删除列表项，如果有子列表则移动到父级。

<API name="removeListItem">
<APIOptions type="RemoveListItemOptions">
  <APIItem name="list" type="ElementEntry">
    包含项的列表条目。
  </APIItem>
  <APIItem name="listItem" type="ElementEntry">
    要删除的列表项。
  </APIItem>
  <APIItem name="reverse" type="boolean" optional>
    是否反转子列表项。
    - **默认：** `true`
  </APIItem>
</APIOptions>

<APIReturns type="boolean">
  项是否被删除。
</APIReturns>
</API>

### `someList`

检查选择是否在特定类型的列表内。

<API name="someList">
<APIParameters>
  <APIItem name="type" type="string">
    要检查的列表类型。
  </APIItem>
</APIParameters>

<APIReturns type="boolean">
  选择是否在指定的列表类型中。
</APIReturns>
</API>

### `unindentListItems`

减少列表项的缩进级别。

<API name="unindentListItems">
<APIOptions type="UnindentListItemsOptions">
    取消缩进的目标路径。
</APIOptions>
</API>

### `unwrapList`

移除选中项的列表格式。

<API name="unwrapList">
<APIOptions type="options">
  <APIItem name="at" type="Path" optional>
    取消包装的目标路径。
  </APIItem>
</APIOptions>
</API>

## Hooks

### `useListToolbarButton`

列表工具栏按钮的行为钩子。

<API name="useListToolbarButton">
<APIState>
  <APIItem name="pressed" type="boolean">
    按钮按下状态。
  </APIItem>
  <APIItem name="nodeType" type="string">
    列表节点类型。
    - **默认：** `BulletedListPlugin.key`
  </APIItem>
</APIState>

<APIReturns type="object">
  <APIItem name="props" type="object">
    工具栏按钮的属性。
  </APIItem>
  <APISubList>
    <APISubListItem parent="props" name="pressed" type="boolean">
      按钮按下状态。
    </APISubListItem>
    <APISubListItem parent="props" name="onClick" type="function">
      切换列表并聚焦编辑器的处理函数。
    </APISubListItem>
  </APISubList>
</APIReturns>
</API>

### `useTodoListElementState`

管理任务列表项状态的钩子。

<API name="useTodoListElementState">
<APIState>
  <APIItem name="element" type="TTodoListItemElement">
    任务列表项元素。
  </APIItem>
</APIState>

<APIReturns type="object">
  <APIItem name="checked" type="boolean">
    任务项是否被选中。
  </APIItem>
  <APIItem name="readOnly" type="boolean">
    编辑器是否处于只读模式。
  </APIItem>
  <APIItem name="onCheckedChange" type="function">
    切换选中状态的处理函数。
  </APIItem>
</APIReturns>
</API>

### `useTodoListElement`

获取任务列表项复选框属性的钩子。

<API name="useTodoListElement">
<APIState>
  <APIItem name="checked" type="boolean">
    任务项是否被选中。
  </APIItem>
  <APIItem name="readOnly" type="boolean">
    编辑器是否处于只读模式。
  </APIItem>
  <APIItem name="onCheckedChange" type="function">
    切换选中状态的处理函数。
  </APIItem>
</APIState>

<APIReturns type="object">
  <APIItem name="checkboxProps" type="object">
    要扩展到复选框组件的属性。
  </APIItem>
</APIReturns>
</API>
